package dormouse.vfs.ui.renderers;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileType;
import org.apache.commons.vfs2.VFS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Predicate;

import dormouse.vfs.event.FileSelectionEventMixin;
import dormouse.vfs.event.ILocationChangeEvent;
import dormouse.vfs.ui.FileButton;
import dormouse.vfs.ui.IconFactory;

/**
 * This class displays a list of files as rows of Icons or Preview images.
 * 
 */
public class FileListCanvas extends AbstractFileListRenderer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6828048399132723196L;
	
	/** Class logger. */
	private static final Logger log = LoggerFactory.getLogger(FileListCanvas.class);
	
	private static Dimension DEFAULT_SIZE = new Dimension(500, 400);

	private static final String HOME = System.getProperty("user.home");

	private JScrollPane scrollPane = new JScrollPane();
	private JPanel innerPanel = new JPanel();
	
	private FileSelectionEventMixin fileSelectMixin = new FileSelectionEventMixin();

	/**
	 * Default constructor for the canvas.
	 * 
	 * @throws FileSystemException
	 * 
	 */
	public FileListCanvas() throws FileSystemException {
		this(VFS.getManager().resolveFile(HOME), true, IconFactory.SIZE_16);
	}

	/**
	 * Constructor
	 * 
	 * @param dir
	 */
	public FileListCanvas(FileObject dir) {
		this(dir, true, IconFactory.SIZE_32);
	}

	/**
	 * This constructor iterates through the files in the directory and creates
	 * icons for each of them and placing them on the canvas.
	 * 
	 * @param dir
	 *            The directory whose contents you want to view.
	 * @param useStdIcons
	 *            Determines whether or not to use standard mime-type based
	 *            icons, or to generate icons for any recognizable image.
	 * @param iconSizeConstant
	 *            One of the IconFactory icons size constants.
	 */
	public FileListCanvas(FileObject dir, boolean useStdIcons,
			int iconSizeConstant) {
		super("View As Icons");
		initialize();
		FileType type = null;
		try {
			type = dir.getType();
		} catch (FileSystemException e) {
			e.printStackTrace();
		}
		if (type == FileType.FOLDER) {
			addChildren(dir, useStdIcons, iconSizeConstant);
		}

	}

	private void initialize() {
		this.setLayout(new BorderLayout());
		this.setPreferredSize(DEFAULT_SIZE);
		this.setSize(DEFAULT_SIZE);
		FlowLayout layout = new FlowLayout();
		layout.setAlignment(FlowLayout.LEADING);
		innerPanel.setLayout(layout);
		innerPanel.setPreferredSize(DEFAULT_SIZE);
		scrollPane
				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane
				.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.getViewport().add(innerPanel);

		this.add(scrollPane, BorderLayout.CENTER);
		this.setVisible(true);
	}

	/**
	 * This method adds a list of files to the canvas.
	 * 
	 * @param files
	 */
	public void addFileList(FileObject[] files, boolean useStdIcons,
			int iconSizeConstant) {
		this.innerPanel.removeAll();
		FileButton currBtn = null;
		for (int i = 0; i < files.length; i++) {
			currBtn = new FileButton(files[i], useStdIcons, iconSizeConstant);
			this.innerPanel.add(currBtn);
		}
	}

	/**
	 * This method adds the children of a given directory to the FileListCanvas.
	 * 
	 * @param dir
	 * @param useStdIcons
	 * @param iconSizeConstant
	 */
	public void addChildren(FileObject dir, boolean useStdIcons,
			int iconSizeConstant) {
		try {
			FileType type = dir.getType();
			if (type == FileType.FOLDER) {
				FileObject[] children = dir.getChildren();// dir.findFiles(Selectors.SELECT_FILES);
				addFileList(children, useStdIcons, iconSizeConstant);
			} else {
				throw new RuntimeException(
						"The FileObject is not a directory.  FileObject:"
								+ dir.getName().getPath());
			}

		} catch (FileSystemException e) {
			e.printStackTrace();
		}

	}

	public void render(FileObject dir) {
		addChildren(dir, true, IconFactory.SIZE_16);
	}

	public void render(String dir) {
		try {
			render(VFS.getManager().resolveFile(dir));
		} catch (FileSystemException e) {
			e.printStackTrace();
		}

	}

	public JComponent getComponent() {
		return this;
	}

	@Override
	public void render(FileObject dir, Predicate<FileObject> predicate) {
		// TODO Auto-generated method stub

	}

	@Override
	public void render(String dir, Predicate<FileObject> predicate) {
		try {
			FileObject file = VFS.getManager().resolveFile(dir);
		} catch (FileSystemException e) {
			log.debug(e.getMessage(), e);
		}

	}

	@Override
	public void render(List<FileObject> fileList,
			Predicate<FileObject> predicate) {
		// TODO Auto-generated method stub

	}

	@Override
	public void notifyFileSelectionListeners(FileObject selectedFile) {
		
		// TODO Auto-generated method stub

	}

	@Override
	public void locationChanged(ILocationChangeEvent event) {
		render(event.getCurrentLocation());
	}
}
